﻿/*
 * Cratos Tools - Data Object
 * Cratos Global class
 * 
 * Copyright (c) 2011-2012 Draco
 * 
 * This file is part of Cratos.
 * 
 * Cratos is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * Cratos is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Cratos.  If not, see <http://www.gnu.org/licenses/>.
 * 
 *       .==.        .==.
 *      //'^\\      //^'\\
 *     // ^ ^\(\__/)/^ ^^\\
 *    //^ ^^ ^/6  6\ ^^ ^ \\
 *   //^ ^^ ^/( .. )\^ ^ ^ \\
 *  // ^^ ^/\| V""V|/\^ ^ ^ \\
 * //^^/\/ /  '~~'  \ \/\^ ^ \\
 *  ------------------------------------
 *  HERE BE DRAGONS
 *  
 *  Johan Dercksen - johan@draco.co.za
 */
using System;
using System.IO;
using System.Diagnostics;
using System.Runtime.Serialization.Formatters.Binary;

using Microsoft.Practices.Unity;

using Cratos.Tools.General;

namespace Cratos.Tools.DataObject
{
	/// <summary>
	/// Cratos Data Object Global class
	/// </summary>
	public static class DOCratosGlobal
	{
		#region Class Constant declarations
		#endregion

		#region Class Event declarations
		#endregion

		#region Class Variable declarations
		#endregion

		#region Class Constructors & Destructors
		/// <summary>
		/// Class Constructor
		/// </summary>
		static DOCratosGlobal()
		{
			// Set the relevant default values
			DOCratosGlobal.DBActionType				    = DOCratosActionType.StoredProcedure.ToString();
			DOCratosGlobal.CollectionMaxNoRecords = 2500;
			DOCratosGlobal.PagingEnabled          = true;
			DOCratosGlobal.PagingMaxNoRecords     = 250;
		}
		#endregion

		#region Class Properties
		/// <summary>
		/// Reference to the current Unity Container
		/// </summary>
		public static IUnityContainer UnityContainer { get; set; }

		/// <summary>
		/// Cratos Entity Access Method
		/// </summary>
		public static string EntityAccessMethod { get; set; }

		/// <summary>
		/// Cratos Entity Collection Access Method
		/// </summary>
		public static string	EntityCollectionAccessMethod { get; set; }

		/// <summary>
		/// Cratos Entity Paging Collection Access Method
		/// </summary>
		public static string EntityPagingCollectionAccessMethod { get; set; }

		/// <summary>
		/// Cratos Database Connection Name
		/// </summary>
		public static string DBConnectionName { get; set; }

		/// <summary>
		/// Cratos Database Action Type
		/// </summary>
		public static string DBActionType { get; set; }

		/// <summary>
		/// Cratos WCF Service Address
		/// </summary>
		public static Uri WcfServiceAddress { get; set; }

		/// <summary>
		/// Cratos Dual WCF Service Address
		/// </summary>
		public static Uri DualWcfServiceAddress { get; set; }

		/// <summary>
		/// Collection Max No records
		/// </summary>
		public static long CollectionMaxNoRecords { get; set; }

		/// <summary>
		/// Paging Enabled indicator
		/// </summary>
		public static bool PagingEnabled { get; set; }

		/// <summary>
		/// Maximum Number of Paging records
		/// </summary>
		public static long PagingMaxNoRecords { get; set; }

		/// <summary>
		/// Persist the Paging Collection indicator
		/// </summary>
		public static bool PagingPersistCollection { get; set; }

		/// <summary>
		/// Paging DB Connection String
		/// </summary>
		public static string PagingDBConnectionString { get; set; }
		#endregion

		#region Class Methods
		/// <summary>
		/// Binary Serializer
		/// </summary>
		/// <param name="objectValue">Object to be serialized</param>
		/// <returns>A byte array representing the serialized object</returns>
		public static byte[] BinSerialize(object objectValue)
		{
			// Declare the required variables
			MemoryStream		memStream;
			BinaryFormatter binFormatter;

#if DEBUG
			Stopwatch	stopWatch = new Stopwatch();
			stopWatch.Start();
#endif

			// Create and setup the relevant objects
			memStream    = new MemoryStream();
			binFormatter = new BinaryFormatter();

			// Serialize and Compress the data
			binFormatter.Serialize(memStream, objectValue);

#if DEBUG
			stopWatch.Stop();
			Trace.WriteLine(string.Format("Serialized {0} in {1}", objectValue.GetType().Name, stopWatch.ElapsedMilliseconds));
#endif

			// Return to calling method
			return (memStream.ToArray());
		}

		/// <summary>
		/// Binary Deserializer
		/// </summary>
		/// <param name="inBuffer">Byte array representing the serialized object</param>
		/// <returns>The deserialized object</returns>
		public static object BinDeserialize(byte[] inBuffer)
		{
			// Declare the required variables
			object					returnValue = null;
			MemoryStream		memStream;
			BinaryFormatter binFormatter;

			// Make sure we have data to work with
			if ((inBuffer == null) || (inBuffer.Length == 0)) { return(returnValue); }

#if DEBUG
			Stopwatch stopWatch = new Stopwatch();
			stopWatch.Start();
#endif

			// Create and setup the relevant objects
			memStream    = new MemoryStream();
			binFormatter = new BinaryFormatter();

			// De-Serialize the Object
			memStream.Write(inBuffer, 0, inBuffer.Length);
			memStream.Position = 0;
			returnValue = binFormatter.Deserialize(memStream);

#if DEBUG
			stopWatch.Stop();
			Trace.WriteLine(string.Format("Deserialized {0} in {1}", returnValue.GetType().Name, stopWatch.ElapsedMilliseconds));
#endif

			// Return to calling method
			return (returnValue);
		}

		/// <summary>
		/// Perform a Deep Clone on an object
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="inObject"></param>
		/// <returns></returns>
		public static T CloneObject<T>(T inObject)
		{
			// Declare the required variables
			MemoryStream		memStream;
			BinaryFormatter binFormatter;

			// Create and setup the relevant objects
			memStream			= new MemoryStream();
			binFormatter	= new BinaryFormatter();

			// Serialize and Compress the data
			binFormatter.Serialize(memStream, inObject);
			memStream.Position = 0;

			// Return to calling method
			return ((T) binFormatter.Deserialize(memStream));
		}

		///// <summary>
		///// Create Serialize Stream from object
		///// </summary>
		///// <param name="value">Object to be serialized</param>
		///// <returns>
		///// A byte array of the serialized object
		///// </returns>
		//public static byte[] CreateSerializeStream<T>(T value)
		//{
		//  // Declare the required variables
		//  MemoryStream memStream;

		//  // Create and setup the relevant objects
		//  memStream = new MemoryStream();

		//  // Serialize the data
		//  Serializer.Serialize<T>(memStream, value);

		//  // Return to calling method
		//  return (memStream.ToArray());
		//}

		///// <summary>
		///// Create Object from a Serialized object
		///// </summary>
		///// <param name="objectStream">A byte array representing the serialized object</param>
		///// <returns>
		///// The recreated object
		///// </returns>
		//public static T CreateObjectFromStream<T>(byte[] objectStream)
		//{
		//  // Declare the required variables
		//  MemoryStream memStream;

		//  // Make sure we have data to work with
		//  if (objectStream.Length > 0)
		//  {
		//    // Create and setup the relevant objects
		//    memStream = new MemoryStream();

		//    // De-Serialize the Object
		//    memStream.Write(objectStream, 0, objectStream.Length);
		//    memStream.Position = 0;

		//    // Serialize the data
		//    return (Serializer.Deserialize<T>(memStream));
		//  }
		//  else
		//  {
		//    // Create an empty object
		//    return(Activator.CreateInstance<T>());
		//  }
		//}
		#endregion

		#region Class Support Methods
		#endregion
	}
}
